/*********************************************************************************
 *      Copyright:  (C) Guo Zixuan
 *                  All rights reserved.
 *
 *       Filename:  get_temp.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(03/04/25)
 *         Author:  Guo Zixuan <guozixuan@gmail.com>
 *      ChangeLog:  1, Release initial version on "03/04/25 19:52:23"
 *                 
 ********************************************************************************/
#include "get_data.h"

int get_temp(float *temp)
{
	int 			openfd = -1;
	char		   *ptr = NULL;
	char			buf[128];
	DIR			   *opdir = NULL;
	struct dirent  *direntp = NULL;
	char			w1_path[64] = "/sys/bus/w1/devices/";
	char			data_path[32];
	int				found = 0;

	opdir=opendir(w1_path);
	if( opdir == NULL)
	{
		log_error("open folder %s failure: %s\n", w1_path, strerror(errno));
		return -1;
	}

	while( NULL != (direntp=readdir(opdir)) )
	{
		if(strstr(direntp->d_name, "28-"))
		{
			strncpy(data_path, direntp->d_name, sizeof(data_path));
			found = 1;
		}
	}

	closedir(opdir);
	if(!found)
	{
		log_error("Can not find ds18b20 chipset\n");
		return -2;
	}

	strncat(w1_path, data_path, sizeof(w1_path)-strlen(w1_path));
	strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));

	openfd=open(w1_path, O_RDONLY);
	if(openfd < 0)
	{
		log_error("open file failure: %s\n", strerror(errno));
		log_error("open file failure\n");
		return -3;
	}

	memset(buf, 0, sizeof(buf));
	if(read(openfd, buf, sizeof(buf)) < 0)
	{
		log_error("read data from openfd=%d failure: %s\n", openfd, strerror(errno));
		return -4;
	}

	ptr=strstr(buf, "t=");
	if(!ptr)
	{
		log_error("Can not find t= string\n");
		return -5;
	}

	ptr += 2;

	*temp = atof(ptr)/1000;
	//log_info("tempreature: %f\n", *temp);

	close(openfd);

	return 0;
}

void get_sn(char *sn, int size)
{
	snprintf(sn, size, "RPI%4d", 1);
}

void get_time(char *mytime, int size)
{
	time_t raw_time;
	struct tm *time_info;

    time(&raw_time);
	time_info = localtime(&raw_time);
	strftime(mytime, size, "%Y-%m-%d %H:%M:%S", time_info);
}

int get_package(data_t *data, uint8_t *buf, int size)
{
	int 	rv;

	memset(buf, 0, size);
	rv = snprintf(buf, size, "%s || %.2f || %s", data->sn, data->temp, data->mytime);

	return rv;
}

int get_package_json(data_t *data, uint8_t *buf, int size)
{
	int 	rv;

	memset(buf, 0, size);
	snprintf(buf, size, "{\"sn\":\"%s\",\"temp\":\"%.2f\",\"time\":\"%s\"}", data->sn, data->temp, data->mytime);

	rv = strlen(buf);
	
	return rv;
}

int get_package_tlv(data_t *data, uint8_t *buf, int size)
{
	int				offset = 0;
	char           *time_str = data->mytime;
	int             year, month, day, hour, minute, second;
	uint16_t        crc;

	memset(buf, 0, size);

	//header (2B)
	*(uint16_t *)buf = htons(0xABCD);
	offset += 2;

	//tag (1B)
	buf[offset++] = 1;
	offset += 2;		//先跳过，后续再计算

	//value:sn
	strncpy((char *)(buf+offset), data->sn, 10);
	offset += 10;

	//value:temp
	buf[offset++] = (int)data->temp;	//整数
	buf[offset++] = ( ( ((int)(data->temp*10000)) % 10000 ) / 100 );	//小数 
	buf[offset++] = ( ( ((int)(data->temp*10000)) % 10000 ) % 100 ); 

	//value:time
	sscanf(time_str, "%4d%2d%2d %2d:%2d:%2d", &year, &month, &day, &hour, &minute, &second);
	buf[offset++] = (uint8_t)(year - 2000);
	buf[offset++] = (uint8_t)month;
	buf[offset++] = (uint8_t)day;
	buf[offset++] = (uint8_t)hour;
	buf[offset++] = (uint8_t)minute;
	buf[offset++] = (uint8_t)second;

	//length
	*(uint16_t *)(buf+3) = (offset-5);

	//crc
	crc = crc_itu_t(buf, offset);
	*(uint16_t *)(buf+offset) = htons(crc);
	offset += 2;

	printf("TLV Package (Hex): ");
	for (int i = 0; i < offset; i++)
	{
		    printf("%02X ", buf[i]); 
	}

	printf("\n");

	return offset;
}

static uint16_t crc_itu_t(const uint8_t *data, size_t length)
{
	uint16_t          crc = 0xFFFF;
	size_t            i, j;

	for (i=0; i<length; i++)
	{
		crc ^= ((uint16_t)data[i] << 8);

		for(j=0; j<8; j++)
		{
			if (crc & 0x8000)
			{
				crc = (crc << 1) ^ CRC16_ITU_T_POLY;
			}
			else
			{
				crc <<= 1;
			}
		}
	}

	return crc;
}
